home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
xinu.arc
/
XINU2.C
< prev
next >
Wrap
Text File
|
1986-01-03
|
30KB
|
1,115 lines
/* conf.c p. 152 */
# include <conf.h>
/* device independent I/O switch */
struct devsw devtab[NDEVS] = {
/* Format of entries is:
major-device-numberè init, open, close,
read, write, seek,
getc, putc, cntl,
device-csr-address, input-vector, output-vector,
iint-handler, oint-handler, control-block, minor-device-number,
*/
/* CONSOLE */
0,
ttyinit, ionull, ionull,
ttyread, ttywrite, ioerr,
ttygetc, ttyputc, ttycntl,
0177560, 0060, 0064,
ttyiin, ttyoin, NULLPTR, 0,
/* OTHER */
1,
ttyinit, ionull, ionull,
ttyread, ttywrite, ioerr,
ttygetc, ttyputc, ttycntl,
0176500, 0300, 0304,
ttyiin, ttyoin, NULLPTR, 1,
/* DISD0 */
2,
dsinit, dsopen, ioerr,
dsread, dswrite, dsseek,
ioerr, ioerr, dscntl,
0177460, 0134, 0134,
dsinter, dsinter, NULLPTR, 0,
/* FILE1 */
3,
lfinit, ioerr, lfclose,
lfread, lfwrite, lfseek,
lfgetc, lfputc, ioerr,
0000000, 0000, 0000,
ioerr, ioerr, NULLPTR, 0,
/* FILE2 */
4,
lfinit, ioerr, lfclose,
lfread, lfwrite, lfseek,
lfgetc, lfputc, ioerr,
0000000, 0000, 0000,
ioerr, ioerr, NULLPTR, 1,
/* FILE3 */
5,
lfinit, ioerr, lfclose,
lfread, lfwrite, lfseek,
lfgetc, lfputc, ioerr,
0000000, 0000, 0000,
ioerr, ioerr, NULLPTR, 2,
è /* FILE4 */
6,
lfinit, ioerr, lfclose,
lfread, lfwrite, lfseek,
lfgetc, lfputc, ioerr,
0000000, 0000, 0000,
ioerr, ioerr, NULLPTR, 3,
/* MEMORY */
7,
ionull, ionull, ioerr,
memread, memwrite, ionull,
ioerr, ioerr, ionull,
0000000, 0000, 0000,
ioerr, ioerr, NULLPTR, 0
};
/* dfckmd.c - dfckmd p. 322 */
#include <conf.h>
#include <kernel.h>
#include <disk.h>
#include <file.h>
/*-----------------------------------------------------------------------------
* dfckmd -- parse file mode argument and generate actual mode bits
*-----------------------------------------------------------------------------
*/
dfckmd(mode)
char *mode;
{
int mbits;
char ch;
mbits = 0;
while (ch = *mode++)
switch(ch) {
case 'r': if (mbits&FLREAD) return(SYSERR);
mbits |= FLREAD;
break;
case 'w': if (mbits&FLWRITE) return(SYSERR);
mbits |= FLWRITE;
break;
case 'o': if (mbits&FLOLD || mbits&FLNEW)
return(SYSERR);
mbits |= FLOLD;
break;
case 'n': if (mbits&FLOLD || mbits&FLNEW)
return(SYSERR);
mbits |= FLNEW;
break;
default: return(SYSERR);
}
if ((mbits&FLREAD) == (mbits&FLWRITE)) /* default: allow r + w */
mbits |= (FLREAD|FLWRITE);
return(mbits);
}
/* dsinter.c - dsinter p. 298 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* dsinter -- process a disk interrupt ( DTC interface; XEBEC controller )
*-----------------------------------------------------------------------------
*/
INTPROC dsinter(dsptr)
struct dsblk *dsptr;
{
struct dtc *dtptr;
struct dreq *drptr;
dtptr = dsptr->dcsr;
drptr = dsptr->dreqlst;
if (drptr == DRNULL) {
panic("disk interrupt when disk not busy");
return;
}
if (dtptr->dt_csr & DTERROR)
drptr->drstat = SYSERR;
else
drptr->drstat = OK;
if ((dsptr->dreqlst=drptr->drnext) != DRNULL)
dskstrt(dsptr);
switch(drptr->drop) {
case DREAD:
case DSYNC:
ready(drptr->drpid,RESCHYES);
return;
case DWRITE:
freebuf(drptr->drbuff);
case DSEEK:
freebuf(drptr);
}
}
/* dsopen.c - dsopen p. 326 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* dsopen -- open/create a file on the specified disk device
*-----------------------------------------------------------------------------
*/
dsopen(devptr, filenam, mode)
struct devsw *devptr;
char *filenam;
char *mode;
{
struct dir *dirptr;
struct flblk *flptr;
struct fdes *fdptr;
DBADDR dba;
int mbits, findex;
int retcode;
char ps;
disable(ps);
dirptr = dsdirec(devptr->dvnum);
if ((mbits=dfckmd(mode)) == SYSERR)
retcode = SYSERR;
else if ((fdptr=dfdsrch(devptr->dvioblk,filenam,mbits))
== (struct fdes *)SYSERR)
retcode = SYSERR;
else if ((findex=dfalloc()) == SYSERR)
retcode = SYSERR;
else {
flptr = &fltab[findex];
flptr->fl_dev = devptr->dvnum;
flptr->fl_dent = fdptr;
flptr->fl_mode = mbits & FLRW;
flptr->fl_iba = fdptr->fdiba;
ibget(flptr->fl_dev,flptr->fl_iba,&(flptr->fl_iblk));
flptr->fl_pos = 0L;
flptr->fl_dch = FALSE;
dba = flptr->fl_iblk.ib_dba[flptr->fl_ipnum = 0];
if (dba != DBNULL) {
read(flptr->fl_dev, flptr->fl_buff, dba);
flptr->fl_bptr = flptr->fl_buff;
} else
flptr->fl_bptr = &flptr->fl_buff[DBUFSIZ];
retcode = flptr->fl_id;
}
restore(ps);
return(retcode);
}
/* freebuf.c - freebuf p. 237 */
# include <conf.h>
# include <kernel.h>
# include <mark.h>
# include <bufpool.h>
/*-----------------------------------------------------------------------------
* freebuf -- free a buffer that was allocated from a pool by getbuf
*-----------------------------------------------------------------------------
*/
freebuf(buf)
int *buf;
{
char ps;
int poolid;
# ifdef MEMMARK
if (unmarked(bpmark))
return(SYSERR);
# endif
poolid = *(--buf);
if (poolid<0 || poolid>=nbpools)
return(SYSERR);
disable(ps);
*buf = bptab[poolid].bpnext;
bptab[poolid].bpnext = buf;
restore(ps);
signal(bptab[poolid].bpsem);
return(OK);
}
/* getitem.c - getfirst, getlast p. 48 */
# include <conf.h>
# include <kernel.h>
# include <q.h>
/*-----------------------------------------------------------------------------
* getfirst -- remove and return the first process on a list
*-----------------------------------------------------------------------------
*/
int getfirst(head)
int head; /* q index of head of list */
{
int proc; /* first process on the list */
if ((proc=q[head].qnext) < NPROC)
return( dequeue(proc) );
else
return(EMPTY);
}
/*-----------------------------------------------------------------------------
* getlast -- remove and return the last process from a list
*-----------------------------------------------------------------------------
*/
int getlast(tail)
int tail; /* q index of tail of list */
{
int proc; /* last process on the list */
if ((proc=q[tail].qprev) < NPROC)
return( dequeue(proc) );
else
return(EMPTY);
}
/* ibclear.c - ibclear p. 311 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* ibclear -- clear in-core copy of an iblock
*-----------------------------------------------------------------------------
*/
ibclear(ibptr, ibbyte)
struct iblk *ibptr;
long ibbyte;
{
int i;
ibptr->ib_byte = ibbyte;
for (i=0 ; i<IBLEN ; i++)
ibptr->ib_dba[i] = DBNULL;
ibptr->ib_next = IBNULL;
}
/* ibput.c - ibput p. 313 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* ibput -- write an iblock back to disk given its number
*-----------------------------------------------------------------------------
*/
ibput(diskdev, inum, loc)
int diskdev;
IBADDR inum;
struct iblk *loc;
{
DBADDR dba;
char *buff;
char *to, *from;
int i;
int ibsem;
dba = ibtodb(inum);
buff = getbuf(dskdbp);
ibsem = ((struct dsblk *)devtab[diskdev].dvioblk)->dibsem;
wait(ibsem);
read(diskdev, buff, dba);
to = buff + ibdisp(inum);
from = (char *)loc;
for (i=0 ; i<sizeof(struct iblk) ; i++)
*to++ = *from++;
write(diskdev, buff, dba);
signal(ibsem);
return(OK);
}
/* insertd.c - insertd p. 127 */
# include <conf.h>
# include <kernel.h>
# include <q.h>
/*-----------------------------------------------------------------------------
* insertd -- insert process pid in delta list "head", given by its key
*-----------------------------------------------------------------------------
*/
insertd(pid, head, key)
int pid;
int head;
int key;
{
int next; /* runs through list */
int prev; /* followes next through list */
for (prev=head,next=q[head].qnext ;
q[next].qkey < key ; prev=next,next=q[next].qnext)
key -= q[next].qkey;
q[pid].qnext = next;
q[pid].qprev = prev;
q[pid].qkey = key;
q[prev].qnext = pid;
q[next].qprev = pid;
if (next < NPROC)
q[next].qkey -= key;
return(OK);
}
/* kill.c - kill p. 71 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <sem.h>
# include <mem.h>
/*-----------------------------------------------------------------------------
* kill -- kill a process and remove it from the system
*-----------------------------------------------------------------------------
*/
SYSCALL kill(pid)
int pid; /* process to kill */
{
struct pentry *pptr; /* points to process table for pid */
char ps; /* saved processor status */
disable(ps);
if (isbadpid(pid) || (pptr= &proctab[pid])->pstate==PRFREE) {
restore(ps);
return(SYSERR);
}
if (--numproc == 0)
xdone();
freestk(pptr->pbase, pptr->pstklen);
switch (pptr->pstate) {
case PRCURR: pptr->pstate = PRFREE; /* suicide */
resched();
case PRWAIT: semaph[pptr->psem].semcnt++;
case PRSLEEP:
case PRREADY: dequeue(pid);
default: pptr->pstate = PRFREE;
}
restore(ps);
return(OK);
}
/* lfinit.c - lfinit p. 340 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# ifdef Ndf
struct flblk fltab[Ndf];
# endif
/*-----------------------------------------------------------------------------
* lfinit -- mark disk file 'device' available at system startup
*-----------------------------------------------------------------------------
*/
lfinit(devptr)
struct devsw *devptr;
{
struct flblk *flptr;
devptr->dvioblk = flptr = &fltab[devptr->dvminor];
flptr->fl_pid = 0;
flptr->fl_id = devptr->dvnum;
return(OK);
}
/* lfseek.c - lfseek p. 332 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* lfseek -- seek to a specified position of a file
*-----------------------------------------------------------------------------
*/
lfseek(devptr, offset)
struct devsw *devptr;
long offset;
{
struct flblk *flptr;
int retcode;
char ps;
disable(ps);
flptr = (struct flblk *)devptr->dvioblk;
if (flptr->fl_mode & FLWRITE) {
if (flptr->fl_dch)
lfsflush(flptr);
} else if (offset > (flptr->fl_dent)->fdlen) {
restore(ps);
return(SYSERR);
}
flptr->fl_pos = offset;
retcode = lfsetup(flptr->fl_dev, flptr);
restore(ps);
return(retcode);
}
/* lfwrite.c - lfwrite p. 338 */
# include <conf.h>
# include <kernel.h>
/*-----------------------------------------------------------------------------
* lfwrite -- write 'count' bytes onto a local disk file
*-----------------------------------------------------------------------------
*/
lfwrite(devptr, buff, count)
struct devsw *devptr;
char *buff;
int count;
{
int i;
if (count < 0)
return(SYSERR);
for (i=count ; i>0 ; i--)
if (lfputc(devptr, *buff++) == SYSERR)
return(SYSERR);
return(count);
}
/* lfputc.c - lfputc p. 336 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* lfputc -- put a character onto a (buffered) disk file
*-----------------------------------------------------------------------------
*/
lfputc(devptr, ch)
struct devsw *devptr;
char ch;
{
struct flblk *flptr;
char ps;
disable(ps);
flptr = (struct flblk *)devptr->dvioblk;
if (flptr->fl_pid!=currpid || !(flptr->fl_mode&FLWRITE)) {
restore(ps);
return(SYSERR);
}
if (flptr->fl_bptr >= &flptr->fl_buff[DBUFSIZ]) {
if (flptr->fl_dch)
lfsflush(flptr);
lfsetup(flptr->fl_dev, flptr);
}
if (flptr->fl_pos >= (flptr->fl_dent)->fdlen)
(flptr->fl_dent)->fdlen++;
flptr->fl_pos++;
*(flptr->fl_bptr)++ = ch;
flptr->fl_dch = TRUE;
restore(ps);
return(OK);
}
/* lfsetup.c - lfsetup p. 331 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* lfsetup -- set up appropriate iblock and data block in memory
*-----------------------------------------------------------------------------
*/
lfsetup(diskdev, flptr)
int diskdev;
struct flblk *flptr;
{
struct iblk *ibptr;
int displ, i;
long ibrange;
IBADDR nextib;
DBADDR dba;
ibrange = (long)(IBLEN * DBUFSIZ);
ibptr = &flptr->fl_iblk;
if (flptr->fl_pos < ibptr->ib_byte) {
flptr->fl_iba = (flptr->fl_dent)->fdiba;
ibget(diskdev, flptr->fl_iba, ibptr);
}
while (ibptr->ib_byte+ibrange <= flptr->fl_pos) {
if (ibptr->ib_next == IBNULL) {
ibptr->ib_next = ibnew(diskdev, IBWDIR);
ibput(diskdev, flptr->fl_iba, ibptr);
flptr->fl_iba = ibptr->ib_next;
ibclear(ibptr, (long)ibptr->ib_byte+ibrange);
ibput(diskdev, flptr->fl_iba, ibptr);
} else {
flptr->fl_iba = ibptr->ib_next;
ibget(diskdev, flptr->fl_iba, ibptr);
}
}
displ = (int)(flptr->fl_pos - ibptr->ib_byte);
for (flptr->fl_ipnum=0 ; displ>=DBUFSIZ ; displ-=DBUFSIZ)
flptr->fl_ipnum++;
flptr->fl_bptr = flptr->fl_buff + displ;
if ((dba=ibptr->ib_dba[flptr->fl_ipnum]) == DBNULL) {
ibptr->ib_dba[flptr->fl_ipnum] = lfsnewd(diskdev,flptr);
ibput(diskdev, flptr->fl_iba, ibptr);
} else
read(diskdev, flptr->fl_buff, dba);
flptr->fl_dch = FALSE;
}
/* control.c - control p. 146 */
#include <conf.h>
#include <kernel.h>
#include <io.h>
/*-----------------------------------------------------------------------------
* control -- control a device ( e.g., set the mode )
*-----------------------------------------------------------------------------
*/
control(descrp, func, addr, addr2)
int descrp, func;
char *addr, *addr2;
{
struct devsw *devptr;
if (isbaddev(descrp))
return(SYSERR);
devptr = &devtab[descrp];
return((*devptr->dvcntl)(devptr, func, addr, addr2));
}
/* dfdsrch.c - dfdsrch p. 324 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* dfdsrch -- search disk directory for positioon of given file name
*-----------------------------------------------------------------------------
*/
struct fdes *dfdsrch(dsptr, filenam, mbits)
struct dsblk *dsptr;
char *filenam;
int mbits;
{
struct dir *dirptr;
struct fdes *fdptr;
int len;
int i;
int inum;
if ((len=strlen(filenam))<=0 || len>=FDNLEN)
return((struct fdes *)SYSERR);
dirptr = dsdirec(dsptr->dnum);
for (i=0 ; i<dirptr->d_nfiles ; i++)
if (strcmp(filenam, dirptr->d_files[i].fdname) == 0)
if ((mbits&FLNEW) != 0)
return((struct fdes *)SYSERR);
else
return(&dirptr->d_files[i]);
wait(dsptr->ddirsem);
if ((mbits&FLOLD) || dirptr->d_nfiles>=NFDES) {
signal(dsptr->ddirsem);
return((struct fdes *)SYSERR);
}
inum = ibnew(dsptr->dnum, IBNWDIR);
fdptr = &(dirptr->d_files[dirptr->d_nfiles++]);
fdptr->fdlen = 0L;
strcpy(fdptr->fdname, filenam);
fdptr->fdiba = inum;
write(dsptr->dnum, dskbcpy(dirptr), DIRBLK);
signal(dsptr->ddirsem);
return(fdptr);
}
/* dskenq.c - dskenq p. 288 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* dskenq -- enqueue a disk request and start I/O if disk not busy
*-----------------------------------------------------------------------------
*/
dskenq(drptr, dsptr)
struct dreq *drptr;
struct dsblk *dsptr;
{
struct dreq *p, *q; /* q follows p through requests */
DBADDR block;
int st;
if ((q=dsptr->dreqlst) == DRNULL) {
dsptr->dreqlst = drptr;
drptr->drnext = DRNULL;
dskstrt(dsptr);
return(DONQ);
}
block = drptr->drdba;
for (p=q->drnext ; p != DRNULL ; q=p, p=p->drnext) {
if (p->drdba==block && (st=dskqopt(p,q,drptr)!=SYSERR))
return(st);
if ((q->drdba <= block && block < p->drdba) ||
(q->drdba >= block && block > p->drdba)) {
drptr->drnext = p;
q->drnext = drptr;
return(DONQ);
}
}
drptr->drnext = DRNULL;
q->drnext = drptr;
return(DONQ);
}
/* dsread.c - dsread p. 293 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <disk.h>
/*-----------------------------------------------------------------------------
* dsread -- read a block from a disk device
*-----------------------------------------------------------------------------
*/
dsread(devptr, buff, block)
struct devsw *devptr;
char *buff;
DBADDR block;
{
struct dreq *drptr;
int stat;
char ps;
disable(ps);
drptr = (struct dreq *) getbuf(dskrbp);
drptr->drdba = block;
drptr->drpid = currpid;
drptr->drbuff = buff;
drptr->drop = DREAD;
if ((stat=dskenq(drptr,devptr->dvioblk)) == DONQ) {
suspend(currpid);
stat = drptr->drstat;
}
freebuf(drptr);
restore(ps);
return(stat);
}
/* freemem.c - freemem p. 110 */
# include <conf.h>
# include <kernel.h>
# include <mem.h>
/*-----------------------------------------------------------------------------
* freemem -- free a memory block, returning it to memlist
*-----------------------------------------------------------------------------
*/
SYSCALL freemem(block, size)
struct mblock *block;
unsigned size;
{
char ps;
struct mblock *p, *q;
unsigned top;
if (size==0 || (unsigned)block>(unsigned)maxaddr
|| ((unsigned)block)<((unsigned)&end))
return(SYSERR);
size = (unsigned) roundew(size);
disable(ps);
for ( p=memlist.mnext,q= &memlist ; p!=NULL && p<block ;
q=p,p=p->mnext )
;
if ((top=q->mlen+(unsigned)q)>(unsigned)block && q!= &memlist ||
p!=NULL && (size+(unsigned)block) > (unsigned)p) {
restore(ps);
return(SYSERR);
}
if ( q!= &memlist && top == (unsigned)block )
q->mlen += size;
else {
block->mlen = size;
block->mnext = p;
q->mnext = block;
q = block;
}
if ((unsigned)(q->mlen + (unsigned)q) == (unsigned)p) {
q->mlen += p->mlen;
q->mnext = p->mnext;
}
restore(ps);
return(OK);
}
/* getmem.c - getmem p. 106 */
# include <conf.h>
# include <kernel.h>
# include <mem.h>
/*-----------------------------------------------------------------------------
* getmem -- allocate heap storage, returning lowest integer address
*-----------------------------------------------------------------------------
*/
int *getmem(nbytes)
unsigned nbytes;
{
char ps;
struct mblock *p, *q, *leftover;
disable(ps);
if (nbytes==0 || memlist.mnext==NULL) {
restore(ps);
return((int *)SYSERR);
}
nbytes = (unsigned) roundew(nbytes);
for (q= &memlist,p=memlist.mnext ; p!=NULL ; q=p,p=p->mnext)
if (p->mlen == nbytes) {
q->mnext = p->mnext;
restore(ps);
return((int *)p);
} else if (p->mlen > nbytes) {
leftover = (struct mblock *)((unsigned)p + nbytes);
q->mnext = leftover;
leftover->mnext = p->mnext;
leftover->mlen = p->mlen - nbytes;
restore(ps);
return((int *)p);
}
restore(ps);
return((int *)SYSERR);
}
/* ibget.c - ibget p. 312 */
# include <conf.h>
# include <kernel.h>
# include <disk.h>
# include <file.h>
# include <dir.h>
/*-----------------------------------------------------------------------------
* ibget -- get an iblock from disk given its number
*-----------------------------------------------------------------------------
*/
ibget(diskdev, inum, loc)
int diskdev;
IBADDR inum;
struct iblk *loc;
{
char *from, *to;
int i;
char *buff;
buff = getbuf(dskdbp);
read(diskdev, buff, ibtodb(inum));
from = buff + ibdisp(inum);
to = (char *)loc;
for (i=0 ; i<sizeof(struct iblk) ; i++)
*to++ = *from++;
freebuf(buff);
}
/* init.c - init p. 147 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
/*-----------------------------------------------------------------------------
* init -- initialize a device
*-----------------------------------------------------------------------------
*/
init(descrp)
int descrp;
{
struct devsw *devptr;
if (isbaddev(descrp))
return(SYSERR);
devptr = &devtab[descrp];
return ((*devptr->dvinit)(devptr));
}
/* ioerr.c - ioerr p. 150 */
# include <conf.h>
# include <kernel.h>
/*-----------------------------------------------------------------------------
* ioerr -- return an error (used for "error" entries in devtab)
*-----------------------------------------------------------------------------
*/
ioerr()
{
return(SYSERR);
}
/* kprintf.c - kprintf, kputc, savestate, rststate p. 358 */
# include <conf.h>
# include <kernel.h>
# include <io.h>
# include <slu.h>
# include <tty.h>
/*-----------------------------------------------------------------------------
* kprintf -- kernel printf: formatted, unbuffered output to CONSOLE
*-----------------------------------------------------------------------------
*/
kprintf(fmt, args)
char *fmt;
{
int kputc();
savestate();
_doprnt(fmt, &args, kputc, CONSOLE);
rststate();
return(OK);
}
/*-----------------------------------------------------------------------------
* kputc -- write a character on the console using polled I/O
*-----------------------------------------------------------------------------
*/
LOCAL kputc(device, c)
int device;
register char c; /* character to print from _doprnt */
{
struct csr *csrptr;
int slowdown; /* delays output at 9600 baud */
if (c == 0)
return;
if (c == NEWLINE)
kputc(device, RETURN);
csrptr = (struct csr *)devtab[device].dvcsr; /* device address */
while ((csrptr->ctstat & SLUREADY) == 0) /* poll for idle */
;
csrptr->ctbuf = c;
for (slowdown=0 ; slowdown<1000 ; slowdown++)
;
while ((csrptr->ctstat & SLUREADY) == 0) /* poll for idle */
;
}
LOCAL int savecrstat, savectstat;
LOCAL char saveps;
/*-----------------------------------------------------------------------------
* savestate -- save the console control and status register
*-----------------------------------------------------------------------------
*/
LOCAL savestate()
{
char ps;
disable(ps);
saveps = ps;
savecrstat = (devtab[CONSOLE].dvcsr)->crstat & SLUENABLE;
(devtab[CONSOLE].dvcsr)->crstat = SLUDISABLE;
savectstat = (devtab[CONSOLE].dvcsr)->ctstat & SLUENABLE;
(devtab[CONSOLE].dvcsr)->ctstat = SLUDISABLE;
}
/*-----------------------------------------------------------------------------
* rststate -- restore the console output control and status register
*-----------------------------------------------------------------------------
*/
LOCAL rststate()
{
char ps;
(devtab[CONSOLE].dvcsr)->crstat = savecrstat;
(devtab[CONSOLE].dvcsr)->ctstat = savectstat;
ps = saveps;
restore(ps);
}
/* initialize.c - nulluser, sysinit p. 192 */
# include <conf.h>
# include <kernel.h>
# include <proc.h>
# include <sem.h>
# include <mem.h>
# include <tty.h>
# include <q.h>
# include <io.h>
# include <disk.h>
extern int main(); /* address of user's main prog */
/* Declarations of major kernel variables */
struct pentry proctab[NPROC]; /* process table */
int nextproc; /* next process slot to use in create*/
struct sentry semaph[NSEM]; /* semaphore table */
int nextsem; /* next sem slot to use in screate */
struct qent q[NQENT]; /* q table ( see queue.c ) */
int nextqueue; /* next slot in q structure to use */
int *maxaddr; /* max memory addr (set by sizemem) */
# ifdef NDEVS
struct intmap intmap[NDEVS]; /* interrupt dispatch table */
# endif
struct mblock memlist; /* list of free memory blocks */
# ifdef Ntty
struct tty tty[Ntty]; /* SLU buffers and mode control */
# endif
/* active system status */
int numproc; /* number of live user processes */
int currpid; /* id of currently running process */
int reboot = 0; /* non-zero after first boot */
/* real-time clock variables and sleeping process queue pointers */
# ifdef RTCLOCK
int count6; /* counts in 60ths of a second 6-0 */
int defclk; /* non-zero, then deferring clock count */
int clkdiff; /* deferred clock ticks */
int slnempty; /* FALSE if sleep queue is empty */
int *sltop; /* address of key part of top entry in the */
/* sleep queue if slnempty == TRUE */
int clockq; /* head of queue of sleeping processes */
int preempt; /* preemption counter. Current process is */
/* preempted when it reaches zero. */
/* set in resched(); counts in ticks */
int clkruns; /* set TRUE iff clock exists by setclkr */
# else
int clkruns = FALSE; /* no clock configured; be sure sleep */
# endif /* doesn't wait forever */
int rdyhead, rdytail; /* head/tail of ready list (q indexes) */
/*****************************************************************************
*** ***
*** NOTE: ***
*** ***
*** This is where the system begins after the C environment has been ***
*** established. Interrupts are initially DISABLED, and must event- ***
*** ually be enabled explicitly. This routine turns itself into the ***
*** null process after initialization. Because the null process must ***
*** always remain ready to run, it cannot execute code that might ***
*** cause it to be suspended, wait for a semaphore, put to sleep, or ***
*** exit. In particular, it must not do I/O unless it uses kprintf ***
*** for polled output. ***
*** ***
*****************************************************************************/
/*-----------------------------------------------------------------------------
* nulluser -- initialize system and become the null process (id == 0)
*-----------------------------------------------------------------------------
*/
nulluser() /* babysit CPU when no one home */
{
char ps;
kprintf("\n\nXinu Version %s", VERSION);
if (reboot++ < 1)
kprintf("\n");
else
kprintf(" (reboot %d)\n", reboot);
sysinit(); /* initialize all of Xinu */
kprintf("%u real mem\n", maxaddr+sizeof(int));
kprintf("%u avail mem\n",
(unsigned)maxaddr-(unsigned)(&end)+(unsigned)sizeof(int));
kprintf("clock %sabled\n", clkruns==1 ? "en" : "dis");
enable(); /* enable interrupts */
/* start a process executing the user's main program */
resume ( create ( main, INITSTK, INITPRIO, INITNAME, 1, 0 ));
while (TRUE) { /* run forever without actually */
pause(); /* executing instructions */
}
}
/*-----------------------------------------------------------------------------
* sysint -- initialize all Xinu data structures and devices
*-----------------------------------------------------------------------------
*/
LOCAL sysinit()
{
int i, j;
struct pentry *pptr;
struct sentry *sptr;
struct mblock *mptr;
numproc = 0; /* initialize system variables */
nextproc = NPROC - 1;
nextsem = NSEM - 1;
nextqueue = NPROC; /* q[0..NPROC-1] are processes */
memlist.mnext = mptr = /* initialize free memory list */
(struct mblock *)roundew(&end);
mptr->mnext = (struct mblock *)NULL;
mptr->mlen = truncew((unsigned)maxaddr - NULLSTK - (unsigned)&end);
for (i=0 ; i<NPROC ; i++) /* initialize process table */
proctab[i].pstate = PRFREE;
pptr = &proctab[NULLPROC]; /* initialize null process entry */
pptr->pstate = PRCURR;
for (j=0 ; j<6 ; j++)
pptr->pname[j] = "prnull"[j];
pptr->plimit = ((int)maxaddr) - NULLSTK;
pptr->pbase = maxaddr;
pptr->paddr = nulluser;
pptr->pargs = 0;
currpid = NULLPROC;
for (i=0 ; i<NSEM ; i++) { /* initialize semaphores */
(sptr = &semaph[i])->sstate = SFREE;
sptr->sqtail = 1 + (sptr->sqhead = newqueue());
}
rdytail = 1 + (rdyhead = newqueue()); /* initialize ready list */
# ifdef MEMMARK
_mkinit(); /* initialize memory marking */
# endif
# ifdef RTCLOCK
clkinit(); /* initialize real time clock */
clockq = newqueue();
# endif
# ifdef Ndsk
dskdbp = mkpool(DBUFSIZ,NDBUFF); /* initialize disk buffers */
dskrbp = mkpool(DREQSIZ,NDREQ);
# endif
for (i=0 ; i<NDEVS ; i++) /* initialize devices */
init(i);
# ifdef NNETS
netinit(); /* initialize networks */
# endif
return(OK);
}